﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace Kristall.Editor.Commands
{
    public class CommandManager
    {
        List<ICommand> _history = new List<ICommand>();
        int _currentCommand = 1;

        public int CurrentCommand
        {
            get
            {
                return _currentCommand;
            }
            internal set
            {
                _currentCommand = value;

                if (CurrentCommandChanged != null)
                    CurrentCommandChanged(this, null);
            }
        }

        public List<ICommand> History
        {
            get
            {
                return _history;
            }
        }

        public event EventHandler HistoryChanged;
        public event EventHandler CurrentCommandChanged;

        public event EventHandler OnExecute;
        public event EventHandler OnUndo;

        public bool ExecuteCommand(ICommand command)
        {
            bool result;
            if (result = command.Execute())
            {
                if (OnExecute != null)
                {
                    OnExecute(command, null);
                }

                if (_history.Any() && _currentCommand < _history.Count)
                {
                    this._history.RemoveRange(_currentCommand, _history.Count - _currentCommand);
                }

                this._history.Add(command);              

                CurrentCommand = _history.Count;

                if (HistoryChanged != null)
                    HistoryChanged(this, null);
            }
            return result;
        }

        public bool Undo()
        {
            if (_currentCommand < 1 || !_history.Any())
                return false;

            if (_history[--CurrentCommand].Undo())
            {
                if (OnUndo != null)
                    OnUndo(_history[CurrentCommand], null);

                return true;
            }

            return false;
        }

        public bool Redo()
        {
            if (_currentCommand > _history.Count - 1)
                return false;

            if (_history[CurrentCommand++].Execute())
            {
                return true;
            }

            return false;
        }

        internal void ClearHistory()
        {
            _history.Clear();
            CurrentCommand = 1;

            if (HistoryChanged != null)
                HistoryChanged(this, null);
        }
    }
}
